
#include "CIOMapping.h"
#include "pugixml/src/pugixml.hpp"
#include <string>
#include <list>


using namespace std;


CIOMapping* CIOMapping::myInstance(NULL);
bool CIOMapping::myInitialization(false);


// -----------------------------------------------------------------------------
// @see header
// -----------------------------------------------------------------------------

CIOMapping::CIOMapping()
{
    myIOMapping.reset();
}


// -----------------------------------------------------------------------------
// @see header
// -----------------------------------------------------------------------------

CIOMapping* CIOMapping::getInstance()
{
    if (NULL == myInstance)
    {
        myInstance = new CIOMapping();
    }
    
    return myInstance;
}


// -----------------------------------------------------------------------------
// @see header
// -----------------------------------------------------------------------------

CIOMapping::~CIOMapping()
{
    myIOMapping.~xml_document();
}


// -----------------------------------------------------------------------------
// @see header
// -----------------------------------------------------------------------------

bool CIOMapping::init()
{
    if (false == myInitialization)
    {
        myInitialization = true;
        
        if (true == parseFile())
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    return true; 
}


// -----------------------------------------------------------------------------
// @see header
// -----------------------------------------------------------------------------

bool CIOMapping::parseFile()
{
    pugi::xml_parse_result parseStatus = myIOMapping.load_file("ioMapping.xml");
    
    if (pugi::status_ok == parseStatus)
    {
        return false;
    }

    return true;
}


// -----------------------------------------------------------------------------
// @see header
// -----------------------------------------------------------------------------

bool CIOMapping::getInputMappedOutputs(const string theInputNumber, list<string> &theMappingList)
{
    theMappingList.clear();
    
    pugi::xml_node theNode = myIOMapping.child("iomapping").child("inputs").find_child_by_attribute("number", theInputNumber.c_str()).child("mapping");

    if (NULL == theNode)
    {
        return false;
    }
    
    theNode = theNode.first_child();
    
    if (NULL == theNode)
    {
        return true;    // No error occurred, but no outputs are mapped
    }
    
    for (; NULL != theNode; theNode = theNode.next_sibling())
    {
        string childName = theNode.name();
        
        if (0 == childName.compare("output"))
        {
            theMappingList.push_back(theNode.first_attribute().value());
        }
    }

    return true;
}


// -----------------------------------------------------------------------------
// @see header
// -----------------------------------------------------------------------------

bool CIOMapping::getInputAlias(const string theInputNumber, string &theAlias)
{
    theAlias = "";
    
    pugi::xml_node theNode = myIOMapping.child("iomapping").child("inputs").find_child_by_attribute("number", theInputNumber.c_str()).child("alias");

    if (NULL != theNode)
    {
        theAlias = theNode.child_value();

        return true;
    }

    return false;
}


// -----------------------------------------------------------------------------
// @see header
// -----------------------------------------------------------------------------

bool CIOMapping::getInputLocation(const string theInputNumber, string &theLocation)
{
    theLocation = "";
    
    pugi::xml_node theNode = myIOMapping.child("iomapping").child("inputs").find_child_by_attribute("number", theInputNumber.c_str()).child("location");

    if (NULL != theNode)
    {
        theLocation = theNode.child_value();

        return true;
    }

    return false;
}


// -----------------------------------------------------------------------------
// @see header
// -----------------------------------------------------------------------------

bool CIOMapping::getOutputAlias(const string theOutputNumber, string &theAlias)
{
    theAlias = "";
    
    pugi::xml_node theNode = myIOMapping.child("iomapping").child("outputs").find_child_by_attribute("number", theOutputNumber.c_str()).child("alias");

    if (NULL != theNode)
    {
        theAlias = theNode.child_value();

        return true;
    }

    return false;
}


// -----------------------------------------------------------------------------
// @see header
// -----------------------------------------------------------------------------

bool CIOMapping::getOutputFunction(const string theOutputNumber, string &theOutputFunction)
{
    theOutputFunction = "";
    
    pugi::xml_node theNode = myIOMapping.child("iomapping").child("outputs").find_child_by_attribute("number", theOutputNumber.c_str()).child("function");

    if (NULL != theNode)
    {
        theOutputFunction = theNode.child_value();

        return true;
    }

    return false;
}


// -----------------------------------------------------------------------------
// @see header
// -----------------------------------------------------------------------------

bool CIOMapping::getOutputLocation(const string theOutputNumber, string &theLocation)
{
    theLocation = "";
    
    pugi::xml_node theNode = myIOMapping.child("iomapping").child("outputs").find_child_by_attribute("number", theOutputNumber.c_str()).child("location");

    if (NULL != theNode)
    {
        theLocation = theNode.child_value();

        return true;
    }

    return false;
}
